package com.ev.custom.service.impl;

import com.ev.apis.model.DsResultResponse;
import com.ev.custom.dao.MaterielDao;
import com.ev.custom.domain.MaterielDO;
import com.ev.custom.service.MaterielService;
import com.ev.custom.vo.MaterielPageParam;
import com.ev.framework.config.Constant;
import com.ev.framework.il8n.MessageSourceHandler;
import com.ev.framework.utils.R;
import com.ev.framework.utils.ShiroUtils;
import com.ev.framework.utils.StringUtils;
import com.ev.scm.domain.StockDO;
import com.ev.scm.vo.MaterielVo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


@Service
public class MaterielServiceImpl implements MaterielService {
	@Autowired
	private MaterielDao materielDao;
	@Autowired
	private MessageSourceHandler messageSourceHandler;


	
	@Override
	public MaterielDO get(Long id){
		return materielDao.get(id);
	}
	
	@Override
	public List<MaterielDO> list(Map<String, Object> map){
		return materielDao.list(map);
	}

	@Override
	public List<MaterielDO> listTwo(Map<String, Object> map){
		return materielDao.listTwo(map);
	}

	@Override
	public List<Map<String, Object>> listForMap(Map<String, Object> map) {
		return materielDao.listForMap(map);
	}

	@Override
	public int count(Map<String, Object> map){
		return materielDao.count(map);
	}
	
	@Override
	public int save(MaterielDO materiel){
	    materiel.setAuditSign(Constant.WAIT_AUDIT);
		return materielDao.save(materiel);
	}
	
	@Override
	public int update(MaterielDO materiel){
		return materielDao.update(materiel);
	}
	
	@Override
	public int remove(Long id){
		return materielDao.remove(id);
	}
	
	@Override
	public int batchRemove(Long[] ids){
		return materielDao.batchRemove(ids);
	}

	@Override
	public int countForMap(Map<String, Object> params) {
		return materielDao.countForMap(params);
	}

	@Override
	public Map<String, Object> getDetail(Long id) {
		Map<String, Object> data = materielDao.getById(id);
		if (data != null && data.size() > 0) {
			data.put("isUse", this.checkUse(id));
			return data;
		}
		return null;
	}

	@Override
	public List<MaterielDO> checkSave(MaterielDO materiel) {
		return materielDao.checkSave(materiel);
	}
	
	@Override
	public List<Map<String, Object>> stockListForMap(Map<String, Object> map) {
		return materielDao.stockListForMap(map);
	}

	@Override
	public List<Map<String, Object>> stockListForMap2(Map<String, Object> map) {
		return materielDao.stockListForMap2(map);
	}

	@Override
	public int stockCountForMap(Map<String, Object> map) {
		return materielDao.stockCountForMap(map);
	}

	@Override
	public List<StockDO> stockList(List<Long> stockIds) {
		return materielDao.stockList(stockIds);
	}

	@Override
	public int checkUse(Long id) {
		return materielDao.checkUse(id);
	}
	
	@Override
	public List<Map<String, Object>> stockCount(Map<String, Object> map) {
		return materielDao.stockCount(map);
	}

	@Override
	public R logicRemove(Long id) {
		if (this.get(id).getAuditSign().equals(Constant.OK_AUDITED)) {
			return R.error(messageSourceHandler.getMessage("common.approvedOrChild.delete.disabled", null));
		}
		if (this.checkUse(id) > 0) {
			return R.error(messageSourceHandler.getMessage("common.delete.disabled", null));

		}
		MaterielDO materielDO = new MaterielDO();
		materielDO.setId(id);
		materielDO.setDelFlag(1);
		return this.update(materielDO)>0?R.ok():R.error();
	}

	@Override
	public R logicBatchRemove(Long[] ids) {
		int count = 0;
		for (Long id : ids) {
			if (this.get(id).getAuditSign().equals(Constant.OK_AUDITED)) {
				return R.error(messageSourceHandler.getMessage("common.approvedOrChild.delete.disabled", null));
			}
			if (this.checkUse(id) > 0) {
				return R.error(messageSourceHandler.getMessage("common.delete.disabled", null));
			}
		}
		MaterielDO materielDO;
		for (Long id : ids) {
			materielDO = new MaterielDO();
			materielDO.setId(id);
			materielDO.setDelFlag(1);
			count += this.update(materielDO);
		}
		return count == ids.length?R.ok():R.error();
	}

    @Override
    public int audit(Long id) {
        MaterielDO materielDO = new MaterielDO();
        materielDO.setId(id);
        materielDO.setAuditSign(Constant.OK_AUDITED);
        materielDO.setAuditor(ShiroUtils.getUserId());
        return this.update(materielDO);
    }

    @Override
    public int reverseAudit(Long id) {
        MaterielDO materielDO = new MaterielDO();
        materielDO.setId(id);
        materielDO.setAuditSign(Constant.WAIT_AUDIT);
        return this.update(materielDO);
    }

    @Override
    public List<String> getAllCode() {
        return materielDao.getAllCode();
    }

    @Override
    public void batchSave(List<MaterielDO> materielDOs) {
        materielDao.batchSave(materielDOs);
    }

	@Override
	public List<String> getAllName() {
		return materielDao.getAllName();
	}

	@Override
	public Map<String, Object> batchList(MaterielPageParam pageParam) {
		Map<String, Object> result = Maps.newHashMap();
		pageParam.setBatchSearch(StringUtils.sqlLike(pageParam.getBatchSearch()));
		List<Map<String,Object>> data = materielDao.batchList(pageParam);
		if (data.size() > 0) {
			int total= materielDao.batchCount(pageParam);
			result.put("data", new DsResultResponse(pageParam.getPageno(), pageParam.getPagesize(), total, data));
		}
		return result;
	}

	@Override
	public R recoverRemoveData(Long[] ids) {
		materielDao.recoverRemoveData(ids);
		return R.ok();
	}

	/**
	 * @Return list.get(0) 单价精度
	 * @Return list.get(1) 数量精度
	*/
	@Override
	public List<Map<Long, Integer>> getAccuracy(List<Long> ids) {
		// 0 单价精度 1 数量精度 2 重量精度
		Map<String, Object> map = Maps.newHashMap();
		map.put("materielIdList", ids);
		List<MaterielDO> materielDOList = this.list(map);
		List<Map<Long, Integer>> list = Lists.newArrayList();
		Map<Long, Integer> priceMap = materielDOList.stream().collect(Collectors.toMap(MaterielDO::getId, e -> e.getPriceAccuracy() != null ? e.getPriceAccuracy() : 0));
		Map<Long, Integer> quantityMap = materielDOList.stream().collect(Collectors.toMap(MaterielDO::getId, e -> e.getQuantityAccuracy() != null ? e.getPriceAccuracy() : 0));
		//Map<Long, Integer> weightMap = materielDOList.stream().collect(Collectors.toMap(MaterielDO::getId, e -> e.getWeightAccuracy() != null ? e.getPriceAccuracy() : 0));
		list.add(priceMap);
		list.add(quantityMap);
		//list.add(weightMap);
		return list;
	}

	@Override
	public int batchUpdate(List<MaterielDO> materiel) {
		return materielDao.batchUpdate(materiel);
	}

	@Override
	public List<Map<String, Object>> findAbleCount(String stockIds) throws Exception {
		return materielDao.findAbleCount(stockIds);
	}

	@Override
	public List<MaterielDO> listForAll() {
		return materielDao.listForAll();
	}


	@Override
	public Map<Long,String> getMaterielS(List<Long> ids) {
		Map<Long,String> map = Maps.newHashMapWithExpectedSize(16);
		List<MaterielVo> materielS = materielDao.getMaterielS(ids);
		if(!CollectionUtils.isEmpty(materielS)){
			materielS.forEach(aa->{
				map.put(aa.getId(),aa.getName());
			});
		}
		return map;
	}

	@Override
	public Map<Long, Integer> getMaterielForSyc(List<Long> ids) {
		List<MaterielVo> materielS = materielDao.getMaterielS(ids);
		Map<Long,Integer> map = Maps.newHashMapWithExpectedSize(16);
		if(!CollectionUtils.isEmpty(materielS)){
			materielS.forEach(aa->{
				if(StringUtils.isNotBlank(aa.getSerialNo())){
					//					附属品 编码开头30-->组装日报-->生产计划类型 2
//					半成品 编码开头20--->成型日报-->生产计划类型 1
					String serialNo = aa.getSerialNo();
					String substring = serialNo.substring(0, 2);
					if(Objects.equals(substring,"30")){
						map.put(aa.getId(),2);
					}
					if(Objects.equals(substring,"20")){
						map.put(aa.getId(),1);
					}
				}
			});
		}
		return map;
	}

}
